//
// Created by liyf on 2021/6/15.
//

#ifndef INC_2_3TREE2_PRINT_H
#define INC_2_3TREE2_PRINT_H

#include "Node.h"
#include <vector>

int GetHeight(Node * root){
    if(root == NULL) return 0;
    int max = 0;
    if(root->children[0])
        max = fmaxl(max,1 + GetHeight(root->children[0]));
    if(root->children[1])
        max = fmaxl(max,1 + GetHeight(root->children[1]));
    if(root->children[2])
        max = fmaxl(max, 1 + GetHeight(root->children[2]));
    return max;
}
//输出间隔
void PrintBlock(int sz){
    for(int i = 0; i < sz; i++)
        printf(" ");
}
void WirteBlock(int sz, FILE * pf){
    for(int i = 0; i < sz; i++)
        fprintf(pf," ");
}
void Node::print() {
    //参数
    int height = GetHeight(this);
    int mSz = height + 1;
    FILE *pf = fopen("pic.txt","a+");   //输出
    //初始化
    //树的二维数组
    vector<vector<Node *>> matrix;
    for(int i = 0; i < mSz; i++){
        vector<Node*> line;
        matrix.push_back(line);
    }

    //存放数值
    Node * cur = this;
    matrix[0].push_back(cur);
    for(int i = 1; i < mSz; i++){
        int pLine = i-1;
        for(int j = 0; j < powl(3,pLine); j++){
            Node * parent = matrix[pLine][j];
            if(parent == nullptr){
                matrix[i].push_back(nullptr);
                matrix[i].push_back(nullptr);
                matrix[i].push_back(nullptr);
            } else {
                matrix[i].push_back(parent->children[0]);
                matrix[i].push_back(parent->children[1]);
                matrix[i].push_back(parent->children[2]);
            }
        }
    }
    //输出
    for(int i = 0; i < mSz; i++){
        int flag = 0;
        int block = 0;
        for(int j = 0; j < powl(3, i); j++){
            Node * pNode = matrix[i][j];

            //头部
            if(flag++ == 0){
                //第一层没有
                //第二层
                if(mSz - i == 2){
                    block = 6;
                    PrintBlock(block);
                    WirteBlock(block,pf);
                }
                //二层以上
                if(mSz - i > 2){
                    block = 6;
                    for(int t = 2; t < mSz - i; t++){
                        block = 3 * block + 2 * 2;
                    }
                    PrintBlock(block);
                    WirteBlock(block,pf);
                }
            }
            //中间
            if(pNode == NULL){//空节点
                printf("**");   //输出little
                fprintf(pf,"**");
                //一层
                if(mSz - i == 1){
                    PrintBlock(2);
                    WirteBlock(2,pf);
                }
                //二层及其以上
                if(mSz - i >= 2){
                    PrintBlock(block);
                    WirteBlock(block,pf);
                }
                printf("**");   //输出large
                fprintf(pf,"**");
            }else {
                printf("%2d",pNode->values[0]);//输出little
                fprintf(pf,"%2d",pNode->values[0]);
                //一层
                if(mSz - i == 1){
                    PrintBlock(2);
                    WirteBlock(2,pf);
                }
                //二层及其以上
                if(mSz - i >= 2){
                    PrintBlock(block);
                    WirteBlock(block,pf);
                }
                if(pNode->szA > 1){ //输出large
                    printf("%2d", pNode->values[1]);
                    fprintf(pf,"%2d",pNode->values[1]);
                }
                else{
                    printf("**");
                    fprintf(pf,"**");
                }

            }
            //尾部
            if(j != powl(3,i) - 1){
                //第一层
                if(mSz - i == 1){
                    PrintBlock(2);//输出2格
                    WirteBlock(2,pf);
                }
                    //二层及其以上
                else if(mSz - i >= 2){
                    int back = block * 2 + 2;
                    PrintBlock(back);
                    WirteBlock(back,pf);
                }
            }
        }
        printf("\n");
        fprintf(pf,"\n");
    }
    //释放二维数组
//    for(int i =0 ; i < mSz; i++){
//        free(matrix[i]);
//        delete matrix;
//    }
//    free(matrix);
//    delete matrix;
//    换行
    int block = 6;
    for(int t = 1; t < mSz; t++){
        block = 3 * block + 2 * 2;
    }
    for(int i = 0; i < block / 2; i++){
        fprintf(pf,"__");
    }
    fprintf(pf,"\n");
    fclose(pf);

}

void Tree::clear(){
    FILE *pf = fopen("pic.txt","w");
    fclose(pf);
};

#endif //INC_2_3TREE2_PRINT_H
